package com.mindata.blockchain.block.queue;

import com.mindata.blockchain.common.ResultPack;
import lombok.extern.slf4j.Slf4j;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.atomic.AtomicInteger;


/**
 * 队列
 * User: jasperxgwang
 * Date: 2018-7-24 11:59
 */
@Slf4j
public class DataQueue<E> {

    private final int capital;

    public DataQueue(int capital) {
        this.capital = capital;
    }

    private ConcurrentLinkedQueue<E> dataQueue = new ConcurrentLinkedQueue<E>();
    /**
     * 单独队列计数，ConcurrentLinkedQueue.size 会执行全队列扫描，影响性能
     */
    private AtomicInteger size = new AtomicInteger(0);

    /**
     * 入队列
     *
     * @param e
     * @return
     */
    public ResultPack<String> offer(E e) {
        if (capital > 0 && size.get() > capital) {
            log.warn("当前队列:{} 超过设置容量:{} data:{}", size.get(), capital, e.toString());
            return ResultPack.failed("超过队列最大容量:" + capital);
        }
        size.incrementAndGet();
        boolean flag = dataQueue.offer(e);
        if (flag) {
            return ResultPack.succeed("success");
        }
        return ResultPack.failed("add queue fail");
    }

    /**
     * 出队列
     *
     * @return
     */
    public E poll() {
        E e = dataQueue.poll();
        if (e != null) {
            size.decrementAndGet();
        }
        return e;
    }


    /**
     * 获取指定出队列数据
     *
     * @param size
     * @return
     */
    public List<E> pollList(int size) {
        List<E> dataList = new ArrayList<>();
        if (size <= 0) {
            return dataList;
        }
        for (int i = 0; i < size; i++) {
            E data = this.poll();
            if (data == null) {
                break;
            } else {
                dataList.add(data);
            }
        }

        return dataList;
    }

    public boolean isEmpty() {
        return dataQueue.isEmpty();
    }

    public int getSize() {
        return size.get();
    }


}
